// src/utils/websocket.ts
import ReceiveMessage from "@/core/communication/ReceiveMessage";

let isInitialized = false;

export class WebSocketClient {
  constructor() {
    this.ws = null;
    this.pairKey = 1;
    this.messageHandlers = new Map();
    this.eventListeners = new Map();
    this.reconnectAttempts = 0;
    this.maxReconnectAttempts = 3;
    this.reconnectDelay = 1000;
    this.heartbeatInterval = 3000;
    this.heartbeatTimer = undefined;
  }

  init() {
    if (!isInitialized) {
      this.connect();
      isInitialized = true;
    }
  }

  connect(url = `ws://${window.location.hostname}:8089`) {
    if (this.ws) {
      console.warn("WebSocket already initialized");
      return;
    }

    try {
      this.ws = new WebSocket(url);
    } catch (e) {
      return;
    }

    //connect消息
    this.ws.onopen = () => {
      this.startHeartbeat();
      this.on("message", (ev) => {
        try {
          const data = JSON.parse(ev.data);
          if (data.data === "heartbeat") return;
          ReceiveMessage.executeEvent(data.type, data);
        } catch (e) {
          console.warn("Message parsing error:", e);
        }
      });
    };

    // 绑定基础事件监听器
    this.ws.addEventListener("open", this.handleOpen);
    this.ws.addEventListener("message", this.handleMessage);
    this.ws.addEventListener("error", this.handleError);
    this.ws.addEventListener("close", this.handleClose);
  }

  handleOpen = (event) => {
    this.emit("open", event);
    this.reconnectAttempts = 0;
  };

  handleMessage = (event) => {
    try {
      if (event.data === "heartbeat") return;
      const message = JSON.parse(event.data);

      // 优先处理系统消息
      if (message.type === "pong") {
        return this.handlePong();
      }

      this.emit("message", event);

      // 触发特定消息类型处理器
      if (message.type && this.messageHandlers.has(message.type)) {
        this.messageHandlers.get(message.type)(message);
      }
    } catch (error) {
      console.error("Message parsing error:", error);
    }
  };

  handleError = (event) => {
    console.error("WebSocket error:", event);
    this.emit("error", event);
  };

  handleClose = (event) => {
    console.log("WebSocket closed:", event.reason);
    this.emit("close", event);
    this.scheduleReconnect();
  };

  sendPairingMessage(message) {
    //只能在已经连接的情况下才能发
    if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
      return;
    }
    const pairingMessage = {
      type: "Web",
      pairKey: this.pairKey,
      data: message,
    };
    this.send(pairingMessage);
  }

  send(data) {
    if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
      console.error("WebSocket not connected");
      return;
    }

    try {
      this.ws.send(JSON.stringify(data));
    } catch (error) {
      console.error("Send message failed:", error);
    }
  }

  on(event, handler) {
    const handlers = this.eventListeners.get(event) || [];
    handlers.push(handler);
    this.eventListeners.set(event, handlers);
  }

  onMessage(type, handler) {
    this.messageHandlers.set(type, handler);
  }

  emit(event, payload) {
    const handlers = this.eventListeners.get(event) || [];
    handlers.forEach((handler) => handler(payload));
  }

  scheduleReconnect() {
    if (this.reconnectAttempts < this.maxReconnectAttempts) {
      setTimeout(() => {
        console.log(`Reconnecting (attempt ${this.reconnectAttempts + 1})`);
        this.connect();
        this.reconnectAttempts++;
      }, this.reconnectDelay * Math.pow(2, this.reconnectAttempts));
    }
  }

  close() {
    if (this.ws) {
      this.ws.close(1000, "Client closed");
      this.cleanup();
    }
  }

  cleanup() {
    if (this.ws) {
      this.ws.removeEventListener("open", this.handleOpen);
      this.ws.removeEventListener("message", this.handleMessage);
      this.ws.removeEventListener("error", this.handleError);
      this.ws.removeEventListener("close", this.handleClose);
      this.ws = null;
    }
    this.messageHandlers.clear();
  }

  startHeartbeat() {
    this.heartbeatTimer = window.setInterval(() => {
      this.sendPairingMessage("heartbeat");
    }, this.heartbeatInterval);
  }

  stopHeartbeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer);
    }
  }

  handlePong() {
    console.debug("Received pong");
  }
}

const wsClient = new WebSocketClient();
export default wsClient;

// 使用示例
export const useWebSocket = () => {
  // 自动重连配置
  // wsClient.on('close', (event) => {
  //   if (!event.wasClean) {
  //     console.log('Connection lost, attempting to reconnect...');
  //   }
  // });

  // 启动心跳检测
  wsClient.on("open", () => {
    wsClient.startHeartbeat();
  });

  return wsClient;
};
